﻿using System;
using System.Linq;

using Ninject;
using Ninject.Modules;

namespace SSTU.Management.Dependency
{
	/// <summary>
	/// Common dependency container with singleton property.
	/// </summary>
	public class DependencyContainer : IDependencyContainer
	{
		private static IDependencyContainer DefaultContainer = new DependencyContainer();
		private static IDependencyContainer CurrentContainer;

		/// <summary>
		/// Initializes the <see cref="DependencyContainer"/> class and singleton instance.
		/// </summary>
		static DependencyContainer()
		{
			Current = DefaultContainer;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DependencyContainer"/> class.
		/// </summary>
		public DependencyContainer()
		{
			IsInitialized = false;
		}

		/// <summary>
		/// Gets the current dependency container associated with application.
		/// </summary>
		public static IDependencyContainer Current
		{
			get { return CurrentContainer; }
			private set { CurrentContainer = value ?? DefaultContainer; }
		}

		/// <summary>
		/// Gets a value indicating whether this instance is initialized.
		/// </summary>
		public bool IsInitialized { get; private set; }

		/// <summary>
		/// Gets the dependency kernel.
		/// </summary>
		public KernelBase Kernel { get; private set; }

		/// <summary>
		/// Occurs when container and all dependencies initialized.
		/// </summary>
		public event Action Initialized;

		/// <summary>
		/// Initializes the specified module, and configure kernel with this module.
		/// </summary>
		/// <param name="module">The module for configuration.</param>
		public void Initialize(INinjectModule module)
		{
			IsInitialized = false;
			Kernel = new StandardKernel(module);
			IsInitialized = true;
			if (Initialized != null)
			{
				Initialized();
			}
		}
	}
}
